home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Mac OS SDK / Dev.CD Jan 98 SDK2.toast / Development Kits (Disc 2) / QuickTime / Programming Stuff / Documentation / develop articles / develop Issue 23 / Internet Config / IC 1.1 / ICAppSourceKit1.1 / ICWindows.p < prev    next >
Encoding:
Text File  |  1997-02-26  |  21.4 KB  |  820 lines  |  [TEXT/PJMM]

  1. unit ICWindows;
  2.  
  3. interface
  4.  
  5.     uses
  6.         ICWindowGlobals;
  7.  
  8.     function InitICWindows: OSErr;
  9.  
  10.     function WindowsOpen (wt: WindowType): OSErr;
  11.     function WindowsClose (wp: WindowPtr): OSErr;
  12.     function WindowsFlushAll: OSErr;    (* close all information windows *)
  13.     function WindowsCloseAll: OSErr;    (* close all information windows *)
  14.  
  15.     procedure WindowsSetTitle (wt: WindowType; title: Str255);
  16.     procedure WindowsIdle;
  17.     procedure WindowActivateDeactivate (window: WindowPtr; activate: boolean);
  18.     procedure WindowItemWhere (window: WindowPtr; er: EventRecord; item: integer);
  19.     procedure WindowsDoKey (er: EventRecord);
  20.     function WindowsEarlyHandleEvent (er: EventRecord): boolean;
  21.     function WindowsEarlyHandleKey (er: EventRecord): boolean;
  22.     procedure WindowsAdjustMenus;
  23.     procedure WindowsDoEditMenu (item: integer);
  24.  
  25.     procedure WindowsRestorePositions;
  26.     procedure WindowsSavePositions;
  27.     procedure WindowsResetPositions;
  28.  
  29.     function GetWindowPtr (wt: WindowType): WindowPtr;
  30.  
  31.     function EditCurrentPreference (var key: Str255): OSErr;
  32.  
  33. implementation
  34.  
  35.     uses
  36.         IconFamilies, 
  37.  
  38.         ICMiscSubs, ICSubs, ICTypes, ICAPI, ICDialogs, ICText, ICGlobals, 
  39.  
  40.         ICTextWhats, ICPopupWhats, ICFontWhats, ICFSSpecWhats, ICFileMapWhat, ICHelperWhat, ICButtonWhat, 
  41.  
  42.         ICDocUtils;
  43.  
  44.  
  45.     function CallWhatOpen (wt: WindowType; item: integer; open: ProcPtr): OSErr;
  46.     inline
  47.         $205F, $4E90;
  48.  
  49.     function CallWhatClose (wt: WindowType; item: integer; close: ProcPtr): OSErr;
  50.     inline
  51.         $205F, $4E90;
  52.  
  53.     function CallWhatFlush (wt: WindowType; item: integer; close: ProcPtr): OSErr;
  54.     inline
  55.         $205F, $4E90;
  56.  
  57.     function CallWhatClick (wt: WindowType; item: integer; er: eventRecord; close: ProcPtr): OSErr;
  58.     inline
  59.         $205F, $4E90;
  60.  
  61.     function CallWhatKey (wt: WindowType; item: integer; er: eventRecord; key: ProcPtr): OSErr;
  62.     inline
  63.         $205F, $4E90;
  64.  
  65.     function CallWhatActivate (wt: WindowType; item: integer; activate: boolean; actproc: ProcPtr): OSErr;
  66.     inline
  67.         $205F, $4E90;
  68.  
  69.     function CallWhatIdle (wt: WindowType; item: integer; idleproc: ProcPtr): OSErr;
  70.     inline
  71.         $205F, $4E90;
  72.  
  73.     function CallWhatCursor (wt: WindowType; item: integer; pt: Point; cursorid: integer; cursorproc: ProcPtr): OSErr;
  74.     inline
  75.         $205F, $4E90;
  76.  
  77.     function TypeToWhat (typ: OSType): integer;
  78.         var
  79.             i: integer;
  80.     begin
  81.         TypeToWhat := 1;
  82.         for i := 1 to whats_max do begin
  83.             if whatinfo[i].typ = typ then begin
  84.                 TypeToWhat := i;
  85.                 leave;
  86.             end;
  87.         end;
  88.     end;
  89.  
  90.     function GetWhatType (wt: WindowType; item: integer): OSType;
  91.         var
  92.             wrp: WhatRecordPtr;
  93.     begin
  94.         wrp := windowinfo[wt].items[item];
  95.         if wrp = nil then begin
  96.             GetWhatType := 'NULL';
  97.         end
  98.         else begin
  99.             GetWhatType := wrp^.typ;
  100.         end;
  101.     end;
  102.  
  103.     function GetWindowPtr (wt: WindowType): WindowPtr;
  104.     begin
  105.         GetWindowPtr := windowinfo[wt].window;
  106.     end;
  107.  
  108.     function OurWindow (wp: WindowPtr): boolean;
  109.     begin
  110.         OurWindow := GetWindowType(wp) <> WT_None;
  111.     end;
  112.  
  113.     function WhatIdleText (wt: WindowType; item: integer; var cursor: integer): OSErr;
  114.         var
  115.             r: rect;
  116.             pt: Point;
  117.     begin
  118.         GetDItemRect(windowinfo[wt].window, item, r);
  119.         GetMouse(pt);
  120.         if PtInRect(pt, r) then begin
  121.             cursor := iBeamCursor;
  122.         end;
  123.         WhatIdleText := noErr;
  124.     end;
  125.  
  126.     procedure DoWindowIdle (window: WindowPtr);
  127.         var
  128.             selected_item, i: integer;
  129.             what: WhatRecordPtr;
  130.             idleproc: ProcPtr;
  131.             wt: WindowType;
  132.             err: OSErr;
  133.             cursorid: integer;
  134.             r: rect;
  135.             pt: Point;
  136.             cursor: ProcPtr;
  137.             junk: OSErr;
  138.             cursor_set: boolean;
  139.     begin
  140.         SetPort(window);
  141.         wt := GetWindowType(window);
  142.         selected_item := GetSelectedItem(GetWindowType(window));
  143.         if selected_item > 0 then begin
  144.             TextIdle(windowinfo[GetWindowType(window)].items[selected_item]^.data);
  145.         end;
  146.         if (window = FrontWindow) & InForeground then begin
  147.             GetMouse(pt);
  148.             cursor_set := false;
  149.             for i := 1 to item_max do begin
  150.                 what := windowinfo[wt].items[i];
  151.                 if what <> nil then begin
  152.                     GetDItemRect(window, i, r);
  153.                     if PtInRect(pt, r) then begin
  154.                         cursor_set := true;
  155.                         cursorid := whatinfo[TypeToWhat(what^.typ)].cursorid;
  156.                         cursor := whatinfo[TypeToWhat(what^.typ)].cursor;
  157.                         if cursor = nil then begin
  158.                             if cursorid = 0 then begin
  159.                                 InitCursor;
  160.                             end
  161.                             else begin
  162.                                 SetCursor(GetCursor(cursorid)^^);
  163.                             end;
  164.                         end
  165.                         else begin
  166.                             junk := CallWhatCursor(wt, i, pt, cursorid, cursor);
  167.                         end; (* if *)
  168.                     end;
  169.                 end; (* if *)
  170.             end; (* for *)
  171.             if not cursor_set then begin
  172.                 InitCursor;
  173.             end; (* if *)
  174.         end;
  175.     end;
  176.  
  177.     procedure WindowDoKey (window: WindowPtr; er: EventRecord);
  178.         var
  179.             selected_item: integer;
  180.             key: ProcPtr;
  181.     begin
  182.         selected_item := windowinfo[GetWindowType(window)].selected_item;
  183.         if selected_item > 0 then begin
  184.             key := whatinfo[TypeToWhat(GetWhatType(GetWindowType(window), selected_item))].key;
  185.             if key <> nil then begin
  186.                 SetPort(window);
  187.                 DisplayError(acDoThis, CallWhatKey(GetWindowType(window), selected_item, er, key));
  188.             end; (* if *)
  189.         end;
  190.     end;
  191.  
  192.     procedure WindowActivateDeactivate (window: WindowPtr; activate: boolean);
  193.         var
  194.             wt: WindowType;
  195.             item: integer;
  196.             i: integer;
  197.             actproc: ProcPtr;
  198.             what: WhatRecordPtr;
  199.             err: OSErr;
  200.     begin
  201.         wt := GetWindowType(window);
  202.         if wt <> WT_None then begin
  203.             SetPort(window);
  204.             item := GetSelectedItem(wt);
  205.             if item > 0 then begin
  206.                 TextActivate(windowinfo[wt].items[item]^.data, activate);
  207.             end; (* if *)
  208.             for i := 1 to item_max do begin
  209.                 what := windowinfo[wt].items[i];
  210.                 if what <> nil then begin
  211.                     actproc := whatinfo[TypeToWhat(what^.typ)].activate;
  212.                     if actproc <> nil then begin
  213.                         err := CallWhatActivate(wt, i, activate, actproc);
  214.                         if (err <> noErr) and (err <> userCanceledErr) then begin
  215.                             SysBeep(10);
  216.                         end; (* if *)
  217.                     end;
  218.                 end; (* if *)
  219.             end; (* for *)
  220.         end; (* if *)
  221.     end;
  222.  
  223.     procedure WindowItemWhere (window: WindowPtr; er: EventRecord; item: integer);
  224.         var
  225.             click: ProcPtr;
  226.     begin
  227.         case GetWindowType(window) of
  228.             WT_About: 
  229.                 ;
  230.             otherwise begin
  231.                 click := whatinfo[TypeToWhat(GetWhatType(GetWindowType(window), item))].click;
  232.                 if click <> nil then begin
  233.                     SetPort(window);
  234.                     DisplayError(acDoThis, CallWhatClick(GetWindowType(window), item, er, click));
  235.                 end; (* if *)
  236.             end;
  237.         end;
  238.     end;
  239.  
  240.     function WindowEarlyHandleEvent (window: WindowPtr; er: EventRecord): boolean;
  241.     begin
  242.         WindowEarlyHandleEvent := false;
  243.     end;
  244.  
  245.     procedure WindowTab (window: WindowPtr; shift: boolean);
  246.         var
  247.             orgitem, rorgitem, i: integer;
  248.             k: integer;
  249.             dirn: integer;
  250.             h: handle;
  251.             r: rect;
  252.             selitem: integer;
  253.             t: OSType;
  254.     begin
  255.         selitem := -1;
  256.         orgitem := GetSelectedItem(GetWindowType(window));
  257.         rorgitem := orgitem;
  258.         if orgitem <= 0 then begin
  259.             if shift then begin
  260.                 orgitem := 1;
  261.             end
  262.             else begin
  263.                 orgitem := item_max;
  264.             end;
  265.         end;
  266.         dirn := item_max - 2 * ord(shift);
  267.         i := orgitem;
  268.         repeat
  269.             i := (i + dirn) mod item_max + 1;
  270.             t := GetWhatType(GetWindowType(window), i);
  271.             if t = 'TEXT' then begin
  272.                 selitem := i;
  273.                 leave;
  274.             end;
  275.         until (i = orgitem);
  276.         if selitem > 0 then begin
  277.             SelectTextItem(GetWindowType(window), selitem);
  278.         end;
  279.     end;
  280.  
  281.     function WindowEarlyHandleKey (window: WindowPtr; er: EventRecord): boolean;
  282.         var
  283.             b: boolean;
  284.             ch: integer;
  285.     begin
  286.         b := false;
  287.         ch := BAND(er.message, $FF);
  288.         if ch = 9 then begin
  289.             WindowTab(window, BAND(er.modifiers, shiftKey) <> 0);
  290.             b := true;
  291.         end;
  292.         if not b then begin
  293.         end;
  294.         WindowEarlyHandleKey := b;
  295.     end;
  296.  
  297.     function FlushWindowType (wp: WindowPtr; wt: WindowType): OSErr;
  298.         var
  299.             i: integer;
  300.             first_err, err: OSErr;
  301.             flush: ProcPtr;
  302.             what: WhatRecordPtr;
  303.             portrect: Rect;
  304.     begin
  305.         first_err := noErr;
  306.         SetPort(wp);
  307.         GetWindowRect(wp, portrect);
  308.         windowinfo[wt].position := portrect.topLeft;
  309.         for i := 1 to item_max do begin
  310.             what := windowinfo[wt].items[i];
  311.             if what <> nil then begin
  312.                 flush := whatinfo[TypeToWhat(what^.typ)].flush;
  313.                 if flush <> nil then begin
  314.                     err := CallWhatFlush(wt, i, flush);
  315.                     if first_err = noErr then begin
  316.                         first_err := err;
  317.                     end; (* if *)
  318.                 end;
  319.             end; (* if *)
  320.         end;
  321.         FlushWindowType := first_err;
  322.     end; (* FlushWindowType *)
  323.  
  324.     function DisposeWindowType (wp: WindowPtr; wt: WindowType): OSErr;
  325.         var
  326.             i: integer;
  327.             first_err, err: OSErr;
  328.             close: ProcPtr;
  329.             what: WhatRecordPtr;
  330.     begin
  331.         first_err := noErr;
  332.         SetPort(wp);
  333.         for i := 1 to item_max do begin
  334.             what := windowinfo[wt].items[i];
  335.             if what <> nil then begin
  336.                 close := whatinfo[TypeToWhat(what^.typ)].close;
  337.                 if close <> nil then begin
  338.                     err := CallWhatClose(wt, i, close);
  339.                     if first_err = noErr then begin
  340.                         first_err := err;
  341.                     end; (* if *)
  342.                 end;
  343.                 windowinfo[wt].items[i] := nil;
  344.                 DisposePtr(Ptr(what));
  345.             end; (* if *)
  346.         end;
  347.         windowinfo[wt].window := nil;
  348.         DisposeDialog(wp);
  349.         DisposeWindowType := first_err;
  350.     end; (* DisposeWindowType *)
  351.  
  352.     function CloseWindowType (wp: WindowPtr; wt: WindowType): OSErr;
  353.         var
  354.             err: OSErr;
  355.             err2: OSErr;
  356.             opened: boolean;
  357.     begin
  358.         opened := false;
  359.         err := ICMapErr(ICBegin(GetInstance, icReadWritePerm));
  360.         if err = noErr then begin
  361.             opened := true;
  362.             err := FlushWindowType(wp, wt);
  363.         end; (* if *)
  364.         err2 := DisposeWindowType(wp, wt);
  365.         if err = noErr then begin
  366.             err := err2;
  367.         end; (* if *)
  368.         if opened then begin
  369.             err2 := ICMapErr(ICEnd(GetInstance));
  370.             if err = noErr then begin
  371.                 err := err2;
  372.             end; (* if *)
  373.         end; (* if *)
  374.         CloseWindowType := err;
  375.     end; (* CloseWindowType *)
  376.  
  377.     function WindowsEarlyHandleEvent (er: EventRecord): boolean;
  378.     begin
  379.         WindowsEarlyHandleEvent := false;
  380.         if GetWindowType(FrontWindow) <> WT_None then begin
  381.             WindowsEarlyHandleEvent := WindowEarlyHandleEvent(FrontWindow, er);
  382.         end;
  383.     end;
  384.  
  385.     function WindowsEarlyHandleKey (er: EventRecord): boolean;
  386.     begin
  387.         WindowsEarlyHandleKey := false;
  388.         if GetWindowType(FrontWindow) <> WT_None then begin
  389.             WindowsEarlyHandleKey := WindowEarlyHandleKey(FrontWindow, er);
  390.         end;
  391.     end;
  392.  
  393.     procedure WindowsDoKey (er: EventRecord);
  394.     begin
  395.         if GetWindowType(FrontWindow) <> WT_None then begin
  396.             WindowDoKey(FrontWindow, er);
  397.         end;
  398.     end;
  399.  
  400.     procedure WindowsIdle;
  401.         var
  402.             wt: WindowType;
  403.     begin
  404.         for wt := WT_None to WT_Last do begin
  405.             if windowinfo[wt].window <> nil then begin
  406.                 DoWindowIdle(windowinfo[wt].window);
  407.             end;
  408.         end;
  409.     end;
  410.  
  411.     procedure WindowsSetTitle (wt: WindowType; title: Str255);
  412.     begin
  413.         if windowinfo[wt].window <> nil then begin
  414.             SetWTitle(windowinfo[wt].window, title);
  415.         end; (* if *)
  416.     end; (* WindowsSetTitle *)
  417.  
  418.     procedure WindowsAdjustMenus;
  419.         var
  420.             wt: WindowType;
  421.     begin
  422.         wt := GetWindowType(FrontWindow);
  423.         AdjustTextMenu(wt);
  424.     end;
  425.  
  426.     procedure WindowsDoEditMenu (item: integer);
  427.         var
  428.             wt: WindowType;
  429.     begin
  430.         wt := GetWindowType(FrontWindow);
  431.         if wt <> WT_None then begin
  432.             DoTextMenu(wt, item);
  433.         end; (* if *)
  434.     end;
  435.  
  436.     type
  437.         WhatTemplateRecord = record
  438.                 key: str31;
  439.                 typ: OSType;
  440.                 flags: longInt;
  441.             end;
  442.         WhatTemplateArray = array[1..item_max] of WhatTemplateRecord;
  443.         WhatTemplateArrayPtr = ^WhatTemplateArray;
  444.         WhatTemplateArrayHandle = ^WhatTemplateArrayPtr;
  445.  
  446.     function ParseWhat (wt: WindowType): OSErr;
  447.         var
  448.             what: WhatTemplateArrayHandle;
  449.             i: integer;
  450.             err: OSErr;
  451.     begin
  452.         err := noErr;
  453.         for i := 1 to item_max do begin
  454.             windowinfo[wt].items[i] := nil;
  455.         end;
  456.         what := WhatTemplateArrayHandle(GetResource('WHAT', windowinfo[wt].id));
  457.         if what <> nil then begin
  458.             HLock(handle(what));
  459.             for i := 1 to GetHandleSize(handle(what)) div SizeOf(WhatTemplateRecord) do begin
  460.                 if what^^[i].typ <> 'NULL' then begin
  461.                     windowinfo[wt].items[i] := WhatRecordPtr(NewPtr(SizeOf(WhatRecord)));
  462.                     err := MemError;
  463.                     if err <> noErr then begin
  464.                         leave;
  465.                     end; (* if *)
  466.                     with windowinfo[wt].items[i]^ do begin
  467.                         key := what^^[i].key;
  468.                         typ := what^^[i].typ;
  469.                         flags := what^^[i].flags;
  470.                     end; (* with *)
  471.                 end; (* if *)
  472.             end; (* for *)
  473.             HUnlock(handle(what));
  474.         end; (* if *)
  475.         ParseWhat := err;
  476.     end; (* ParseWhat *)
  477.  
  478.     function GetWindowID (wt: WindowType): integer;
  479.     begin
  480.         if wt = WT_About then begin
  481.             GetWindowID := 128;
  482.         end
  483.         else begin
  484.             GetWindowID := 200 + ord(wt) - ord(WT_Main);
  485.         end;
  486.     end;
  487.  
  488.     function EditCurrentPreference (var key: Str255): OSErr;
  489.         var
  490.             wt: WindowType;
  491.             what: WhatTemplateArrayHandle;
  492.             err: OSErr;
  493.             i: integer;
  494.             id: integer;
  495.     begin
  496.         err := -1;
  497.         for wt := WT_None to WT_Last do begin
  498.             if (WT_Personal <= wt) & (wt <= WT_Last) then begin
  499.                 id := GetWindowID(wt);
  500.                 what := WhatTemplateArrayHandle(GetResource('WHAT', id));
  501.                 if what <> nil then begin
  502.                     HLock(handle(what));
  503.                     for i := 1 to GetHandleSize(handle(what)) div SizeOf(WhatTemplateRecord) do begin
  504.                         if IUEqualString(key, what^^[i].key) = 0 then begin
  505.                             err := WindowsOpen(wt);
  506.                             if (what^^[i].typ = 'TEXT') then begin
  507.                                 SelectTextItem(wt, i);
  508.                             end;
  509.                         end;
  510.                     end;
  511.                     HUnlock(handle(what));
  512.                 end;
  513.             end;
  514.         end;
  515.         EditCurrentPreference := err;
  516.     end;
  517.  
  518.     function PrepWindow (wt: WindowType; id: integer; wp: WindowPtr): OSErr;
  519.         var
  520.             what, i: integer;
  521.             err: OSErr;
  522.             first_err: OSErr;
  523.     begin
  524.         SetPort(wp);
  525.         windowinfo[wt].window := wp;
  526.         windowinfo[wt].id := id;
  527.         windowinfo[wt].selected_item := -1;
  528.         first_err := ParseWhat(wt);
  529.         if first_err = noErr then begin
  530.             for i := 1 to item_max do begin
  531.                 if windowinfo[wt].items[i] <> nil then begin
  532.                     with windowinfo[wt].items[i]^ do begin
  533.                         what := TypeToWhat(typ);
  534.                         if whatinfo[what].open <> nil then begin
  535.                             err := CallWhatOpen(wt, i, whatinfo[what].open);
  536.                             if first_err = noErr then begin
  537.                                 first_err := err;
  538.                             end; (* if *)
  539.                         end;
  540.                     end; (* with *)
  541.                 end;
  542.             end; (* for *)
  543.         end; (* if *)
  544.         if first_err = noErr then begin
  545.             if windowinfo[wt].selected_item = -1 then begin
  546.                 WindowTab(windowinfo[wt].window, false);
  547.             end; (* if *)
  548.         end; (* if *)
  549.         PrepWindow := first_err;
  550.     end; (* PrepWindow *)
  551.  
  552.     function NewWindow (wt: WindowType): OSErr;
  553.         var
  554.             wp: WindowPtr;
  555.             junk: OSErr;
  556.             position: Point;
  557.             original_position: Rect;
  558.             err: OSErr;
  559.             err2: OSErr;
  560.             id, dlg_id: integer;
  561.     begin
  562.         id := GetWindowID(wt);
  563.         wp := nil;
  564.         err := ICMapErr(ICBegin(GetInstance, icReadWritePerm));
  565.         if err = noErr then begin
  566.             dlg_id := id;
  567.             if (wt = WT_Font) & not system7 then begin
  568.                 dlg_id := 290;
  569.             end;
  570.             wp := GetNewDialog(dlg_id, nil, POINTER(-1));
  571.             if wp = nil then begin
  572.                 err := memFullErr;
  573.             end; (* if *)
  574.             if err = noErr then begin
  575.                 err := PrepWindow(wt, id, wp);
  576.             end; (* if *)
  577.             if err = noErr then begin
  578.                 position := windowinfo[wt].position;
  579.                 if (position.h <> 0) or (position.v <> 0) then begin
  580.                     GetWindowRect(wp, original_position);
  581.                     MoveWindow(wp, position.h, position.v, false);
  582.                     ShowWindow(wp);            (* because TitleBarOnScreen requires window to be shown *)
  583.                     if not TitleBarOnScreen(wp) then begin
  584.                         MoveWindow(wp, original_position.left, original_position.top, false);
  585.                     end; (* if *)
  586.                 end; (* if *)
  587.                 ShowWindow(wp);
  588.             end;
  589.             err2 := ICMapErr(ICEnd(GetInstance));
  590.             if err = noErr then begin
  591.                 err := err2;
  592.             end; (* if *)
  593.         end; (* if *)
  594.         (* tidy up code *)
  595.         if err <> noErr then begin
  596.             if wp <> nil then begin
  597.                 junk := DisposeWindowType(wp, wt);
  598.             end; (* if *)
  599.         end; (* if *)
  600.         NewWindow := err;
  601.     end; (* NewWindow *)
  602.  
  603.     function WindowsOpen (wt: WindowType): OSErr;
  604.     begin
  605.         if windowinfo[wt].window <> nil then begin
  606.             ShowWindow(windowinfo[wt].window);
  607.             SelectWindow(windowinfo[wt].window);
  608.             WindowsOpen := noErr;
  609.         end
  610.         else begin
  611.             WindowsOpen := NewWindow(wt);
  612.         end;
  613.     end; (* WindowsOpen *)
  614.  
  615.     function WindowsClose (wp: WindowPtr): OSErr;
  616.         var
  617.             wt: WindowType;
  618.     begin
  619.         WindowsClose := noErr;
  620.         wt := GetWindowType(wp);
  621.         if wt <> WT_None then begin
  622.             WindowsClose := CloseWindowType(wp, wt);
  623.         end; (* if *)
  624.     end; (* WindowsClose *)
  625.  
  626.     type
  627.         pointArray = array[WT_Main..WT_Last] of Point;
  628.  
  629.     procedure WindowsResetPositions;
  630.         var
  631.             wt: WindowType;
  632.             pos: Point;
  633.     begin
  634.         pos.h := 2;
  635.         pos.v := 42;
  636.         for wt := WT_Main to pred(WT_Last) do begin
  637.             windowinfo[wt].position := pos;
  638.             pos.h := pos.h + 20 * ord(screenbits.bounds.right > 512);
  639.             pos.v := pos.v + 10 * ord(screenbits.bounds.bottom >= 400) + 8 * ord(screenbits.bounds.bottom >= 480);
  640.         end; (* for *)
  641.     end;
  642.  
  643.     procedure WindowsRestorePositions;
  644.         var
  645.             err, err2: OSErr;
  646.             key: Str255;
  647.             attr: longint;
  648.             window_positions: pointArray;
  649.             size: longint;
  650.             wt: WindowType;
  651.     begin
  652.         err := ICMapErr(ICBegin(GetInstance, icReadOnlyPerm));
  653.         if err = noErr then begin
  654.             key := StringOf(Ptr(longint(ICcreator)), '•WindowPositions');
  655.             size := sizeof(window_positions);
  656.             err := ICGetPref(GetInstance, key, attr, @window_positions, size);
  657.             if (err = noErr) and (size <> sizeof(window_positions)) then begin
  658.                 err := -1;
  659.             end; (* if *)
  660.             err2 := ICMapErr(ICEnd(GetInstance));
  661.             if err = noErr then begin
  662.                 err := err2;
  663.             end; (* if *)
  664.         end; (* if *)
  665.         if err = noErr then begin
  666.             for wt := WT_Main to WT_Last do begin
  667.                 windowinfo[wt].position := window_positions[wt];
  668.             end; (* for *)
  669.         end
  670.         else begin
  671.             WindowsResetPositions;
  672.         end; (* if *)
  673.     end; (* WindowsRestorePositions *)
  674.  
  675.     procedure WindowsSavePositions;
  676.         var
  677.             err, err2: OSErr;
  678.             wt: WindowType;
  679.             key: Str255;
  680.             window_positions: pointArray;
  681.     begin
  682.         for wt := WT_Main to WT_Last do begin
  683.             window_positions[wt] := windowinfo[wt].position;
  684.         end; (* for *)
  685.         err := ICMapErr(ICBegin(GetInstance, icReadWritePerm));
  686.         if err = noErr then begin
  687.             key := StringOf(Ptr(longint(ICcreator)), '•WindowPositions');
  688.             err := ICSetPref(GetInstance, key, ICattr_no_change, @window_positions, sizeof(window_positions));
  689.             err2 := ICMapErr(ICEnd(GetInstance));
  690.             if err = noErr then begin
  691.                 err := err2;
  692.             end; (* if *)
  693.         end; (* if *)
  694.     end; (* WindowsSavePositions *)
  695.  
  696.     function WindowsFlushAll: OSErr;    (* flush all information windows *)
  697.         var
  698.             wt: WindowType;
  699.             first_err, err: OSErr;
  700.     begin
  701.         first_err := ICMapErr(ICBegin(GetInstance, icReadWritePerm));
  702.         if first_err = noErr then begin
  703.             for wt := WT_Main to WT_Last do begin
  704.                 if windowinfo[wt].window <> nil then begin
  705.                     SetPort(windowinfo[wt].window);
  706.                     err := FlushWindowType(windowinfo[wt].window, wt);
  707.                     if first_err = noErr then begin
  708.                         first_err := err;
  709.                     end; (* if *)
  710.                 end; (* if *)
  711.             end; (* for *)
  712.             err := ICMapErr(ICEnd(GetInstance));
  713.             if first_err = noErr then begin
  714.                 first_err := err;
  715.             end; (* if *)
  716.         end; (* if *)
  717.         WindowsFlushAll := first_err;
  718.     end; (* WindowsFlushAll *)
  719.  
  720.     function WindowsCloseAll: OSErr;    (* close all information windows *)
  721.         var
  722.             wt: WindowType;
  723.             err, first_err: OSErr;
  724.     begin
  725.         first_err := noErr;
  726.         for wt := WT_Personal to WT_Last do begin
  727.             if windowinfo[wt].window <> nil then begin
  728.                 err := CloseWindowType(windowinfo[wt].window, wt);
  729.                 if first_err = noErr then begin
  730.                     first_err := err;
  731.                 end; (* if *)
  732.             end;
  733.         end; (* for *)
  734.         WindowsCloseAll := first_err;
  735.     end; (* WindowsCloseAll *)
  736.  
  737.     procedure InitWhats;
  738.         procedure W (what: integer; xtyp: OSType; xopen, xkey, xclick, xidle, xflush, xclose, xactivate, xcursor: ProcPtr; xcursorid: integer);
  739.         begin
  740.             with whatinfo[what] do begin
  741.                 typ := xtyp;
  742.                 open := xopen;
  743.                 key := xkey;
  744.                 click := xclick;
  745.                 flush := xflush;
  746.                 close := xclose;
  747.                 activate := xactivate;
  748.                 idle := xidle;
  749.                 cursor := xcursor;
  750.                 cursorid := xcursorid;
  751.             end;
  752.         end;
  753.     begin
  754.         W(1, 'NULL', nil, nil, nil, nil, nil, nil, nil, nil, 0);
  755.         W(2, 'TEXT', @WhatOpenText, @WhatKeyText, @WhatClickText, nil, @WhatFlushText, @WhatCloseText, nil, nil, iBeamCursor);
  756.         W(3, 'SPOP', @WhatOpenPopup, nil, @WhatClickPopup, nil, @WhatFlushPopup, @WhatClosePopup, nil, nil, 0);
  757.         W(4, 'FFSP', @WhatOpenFSSpec, nil, @WhatClickFSSpec, nil, @WhatFlushFSSpec, nil, nil, nil, 0);
  758.         W(5, 'FPOP', @WhatOpenFont, nil, @WhatClickFont, nil, @WhatFlushFont, nil, nil, nil, 0);
  759.         W(6, 'FMAP', @WhatOpenFileMap, @WhatKeyFileMap, @WhatClickFileMap, nil, @WhatFlushFileMap, @WhatCloseFileMap, @WhatActivateFileMap, @WhatCursorFileMap, plusCursor);
  760.         W(7, 'FBUT', nil, nil, @WhatClickFileMap, nil, nil, nil, nil, nil, 0);
  761.         W(8, 'HMAP', @WhatOpenHelper, @WhatKeyHelper, @WhatClickHelper, nil, @WhatFlushHelper, @WhatCloseHelper, @WhatActivateHelper, @WhatCursorHelper, plusCursor);
  762.         W(9, 'HBUT', nil, nil, @WhatClickHelper, nil, nil, nil, nil, nil, 0);
  763.         W(10, 'BUTN', @WhatOpenButton, nil, @WhatClickButton, nil, nil, nil, nil, nil, 0);
  764.         W(11, 'FSIZ', nil, nil, @WhatClickFontSize, nil, nil, nil, nil, nil, 0);
  765.     end;
  766.  
  767.     procedure AboutBoxUpdate (dlg: DialogPtr; item: integer);
  768.         var
  769.             r: Rect;
  770.     begin
  771.         GetDItemRect(dlg, item, r);
  772.         case item of
  773.             1: 
  774.                 DrawIcon(128, r, false);
  775.             3: 
  776.                 DisplayStyledString(dlg, item, concat(GetAString(129, item), app_version.shortVersion));
  777.             otherwise
  778.                 DisplayStyledString(dlg, item, GetAString(129, item));
  779.         end; (* case *)
  780.     end; (* AboutBoxUpdate *)
  781.  
  782.     function InitICWindows: OSErr;
  783.         var
  784.             wt: WindowType;
  785.             i: integer;
  786.             pos: Point;
  787.             wp: WindowPtr;
  788.             kind: integer;
  789.             err: OSErr;
  790.     begin
  791.         InitICWindowGlobals;
  792.         InitWhats;
  793.         for wt := WT_None to WT_Last do begin
  794.             windowinfo[wt].window := nil;
  795.             windowinfo[wt].position.h := 0;
  796.             windowinfo[wt].position.v := 0;
  797.         end;
  798.         WindowsResetPositions;
  799.         (* bring the about box up hidden and leave it there *)
  800.         err := noErr;
  801.         wp := GetNewDialog(128, nil, WindowPtr(-1));
  802.         windowinfo[WT_About].window := wp;
  803.         if wp = nil then begin
  804.             err := memFullErr;
  805.         end; (* if *)
  806.         if err = noErr then begin
  807.             err := PrepWindow(WT_About, 128, wp);
  808.         end; (* if *)
  809.         if err = noErr then begin
  810.             for i := 1 to CountDItems(wp) do begin
  811.                 GetDItemKind(wp, i, kind);
  812.                 if band(kind, $7f) = userItem then begin
  813.                     SetDItemHandle(wp, i, @AboutBoxUpdate);
  814.                 end; (* if *)
  815.             end; (* for *)
  816.         end; (* if *)
  817.         InitICWindows := err;
  818.     end; (* InitICWindows *)
  819.  
  820. end.